package org.example.onlinejudge.config;

import org.example.onlinejudge.service.CustomUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

/**
 * Spring Security配置类
 * 负责配置系统的安全策略，使用基于数据库的RBAC认证和授权
 * 实现逻辑：
 * 1. 配置URL访问权限：根据角色（管理员0、教师1、学生2）控制不同页面的访问
 * 2. 配置登录和登出流程：自定义登录成功和登出成功处理器
 * 3. 配置认证提供者：使用自定义UserDetailsService和BCrypt密码加密
 * 4. 配置异常处理：指定访问被拒绝时的跳转页面
 */
@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true)
public class SecurityConfig {

    @Autowired
    private CustomUserDetailsService customUserDetailsService;

    @Autowired
    private CustomAuthenticationSuccessHandler authenticationSuccessHandler;

    @Autowired
    private CustomLogoutSuccessHandler logoutSuccessHandler;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            // 暂时禁用CSRF（开发阶段）- 生产环境请启用并正确配置
            .csrf(csrf -> csrf.disable())
            .authorizeHttpRequests(authorizeRequests -> 
                authorizeRequests
                    // 允许访问登录、注册等公共资源
                    .requestMatchers("/login", "/register", "/perform_register", "/perform_logout", "/test", "/test-post", "/css/**", "/js/**", "/images/**").permitAll()
                    // 管理员专属页面（角色代码：0）
                    .requestMatchers("/admin/**", "/api/**").hasRole("0")
                    // 老师专属页面（角色代码：1）
                    .requestMatchers("/teacher/**").hasAnyRole("0", "1")
                    // 学生页面（角色代码：2）
                    .requestMatchers("/student/**").hasAnyRole("0", "1", "2")
                    // 其他所有请求都需要认证
                    .anyRequest().authenticated()
            )
            .formLogin(formLogin ->
                formLogin
                    .loginPage("/login")
                    .loginProcessingUrl("/perform_login")
                    .successHandler(authenticationSuccessHandler)
                    .failureUrl("/login?error=true")
                    .permitAll()
            )
            .logout(logout ->
                logout
                    .logoutUrl("/logout")
                    .logoutSuccessHandler(logoutSuccessHandler)
                    .invalidateHttpSession(true)
                    .clearAuthentication(true)
                    .deleteCookies("JSESSIONID")
                    .permitAll()
            )
            .exceptionHandling(exceptionHandling ->
                exceptionHandling
                    .accessDeniedPage("/access-denied")
            );
        
        return http.build();
    }

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(customUserDetailsService);
        authProvider.setPasswordEncoder(passwordEncoder());
        return authProvider;
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
        return authConfig.getAuthenticationManager();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
